home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D-,E-,F-,G+,I+,L-,N-,O-,R-,S-,V+,X-}
- Unit Mdrive;
- Interface
- Uses Dos,Objects;
-
- { (c) Emilio David Diaus López 1994 }
- { MicroDrive: subconjunto de útiles para el acceso a disquetes }
- { Es un subconjunto de las funciones existentes en Superdrv.pas }
- {
- 7. Mdrive: MαDulo De Manejo De Disquetes
-
- Este MóDulo Ha Sido DiseñAdo Mediante La ProgramacióN Orientada
- A Objetos Y Realiza Las Funciones De AnáLisis De Unidades De
- Disquete, Escritura, Lectura Y Formato De Pistas Y Cambio De
- ParáMetros.
-
- El Objeto Fundamental De Este MóDulo Es Tdrive, Objeto En El
- Que EstáN Todos Los MéTodos Y Variables Necesarios Para Operar
- Con Disquetes.
-
-
- En El Objeto Mencionado Por Una Parte Tenemos Los Datos Del
- Disquete Y Por Otra Los MéTodos De Acceso Al Disquete, Dentro De
- Estos úLtimos Tenemos :
-
- Constructor Init (Unidad:Byte);
- Inicializa El Objeto Y Analiza El Disquete
- Identificado Con El NúMero De Unidad LóGica Unidad.
- Function Actualizar :Word;
- Actualiza Los Datos Del Disquete Introducido En La
- Unidad LóGica Actual.
- Function Leesector;
- Lee Un Sector Del Disquete.
- Function Leepista;
- Lee Una Pista Del Disquete.
-
- El Contenido Del Sector Se Almacena En Disco.Sector Y El
- Contenido De La Pista En Disco.Pista.
- Las Funciones De Manejo De Sectores Necesitan Tres ParáMetros,
- La Cara Del Disquete (0 O 1), El NúMero De Pista Donde Esta El
- Sector (40,80) Y El NúMero De Sector Que Queremos Leer o
- Escribir.
- Function Grabapista;
- Graba El Contenido De Disco.Pista En Una Pista FíSica
- Del Disquete Actual.
- Function Verificapista;
- Verifica Una Pista Determinada.
- Function Format;
- Da Formato A Una Pista, Antes De Realizar Ningún
- Formato Hay Que Definir El Tipo De Medio Adecuado Para
- El Formato De La Unidad Por Medio Del MéTodo
- Definemedio.
- Las Funciones De Pistas Necesitan Dos ParáMetros: La Cara Del
- Disquete (0 O 1) Y El NúMero De Pista (40,80).
-
- Procedure Reinicia_Unidad;
- Se Encarga De Reiniciar La Unidad Actual En Caso De
- Que Haya Ocurrido Un Error O Al Efectuar El AnáLisis
- De Un Disquete.
-
-
-
-
- Function Buscar_Tipo_Unidad;
- Devuelve El CóDigo De La Unidad Actual, Los CóDigos
- Posibles Son:
-
- Tipo CóDigo
- 51/4 320/360 Kb 01h
- 51/4 1200 Kb 02h
- 31/2 720 Kb 03h
- 31/2 1440 Kb 04h
- 31/2 2880 Kb 05h
-
-
- El úLtimo De Unidades De Extra Densidad ( 31/2 2880 Kb
- CóDigo 05H) Hay Que Suponerlo Porque Es Reciente Su
- ImplementacióN Y Puede No Estar Estandarizado. Todos Los
- NúMeros De La Tabla Que Finalizan Con 'h' Son En
- Formato Hexadecimal.
-
- Function Leer_Arranque;
- Lee El Sector De Arranque Del Disquete Y Lo Coloca En
- La Matriz De Bytes Arranque Para Su Posterior
- Procesamiento Por El MéTodo Actualizar.
- Destructor Done;Virtual;
- Reinicializa La Unidad De Disquete Y Finaliza La
- GestióN De Los Disquetes.
-
- Function Calcula_Capacidad:Byte;
- Se Sirve De La FuncióN Del Dos A.P.I 36H Para
- Averiguar Parte De Los ParáMetros LóGicos Del Disquete
- Introducido.
-
- AdemáS De Estas Funciones Hay Dos Que Toman Como Base Las
- Interrupciones Int 25H E Int 26H Del Dos Para Acceder A Los
- Disquetes Mediante Sectores LóGicos En Vez De Acceder Por Medio
- De Sectores FíSicos. Su ImplementacióN Requiere Ensamblador
- Porque Una Llamada Directa Cuelga El Ordenador, Para Que Esto No
- Ocurra Se Introduce DespuéS De La Llamada La InstruccióN 'popf'
- Que Coloca Los Flags En El Stack, Esto Es Requerido Para El
- Correcto Funcionamiento De Esta FuncióN.
-
- El Procedimiento De Funcionamiento Es El Normal En Estos Casos,
- Inicializar El Disquete Por Medio De Init, Efectuar Las Acciones
- Necesarias Y Finalizar Su Funcionamiento Con Done.
- }
- Const
- Cread =2;
- Cwrite =3;
- Cverify =4;
- Cformat =5;
- Const
- Cerrbytessecinc = $81; { Bytes por sector no válido }
- Cerrsecporclinc = $82; { Sectores por cluster no válido }
- Cerrdescrmedinc = $83; { Descriptor de medio no válido }
- Cerrsecporpinc = $84; { Sectores por pista no válido }
- Cerrnumheadinc = $85; { Número de cabezas no válido }
- Cerrunidileg = $86; { Unidad ilegible }
- Cerrunidadvacia = $8002;
-
-
- { Tipos necesarios }
- Type Tipounidad=(Knone,K360,K1200,K720,K1440,K2880); { Tipos de unidad }
- Tsector=Array [1..512] Of Byte; { Tipo Sector de 512kb }
- Tpista=Array[1..512*36] Of Byte; { Tipo pista }
- Tbuffer = Array [1..124] Of Byte; { Tipo Buffer para el formato }
- Tstr8 = String [8]; { Tipo de cadena }
- Ttable = Array [0..10] Of Byte; { Tipo de Tabla parametros disco }
- Ptable =^Ttable; { Tipo puntero de tabla }
-
- Type
- Tdrive=Object(Tobject)
- { --- Parámetros Físicos --- }
- Numero_Fisico:Byte;
- Cabezas,
- Pistas,Sectores_Por_Pista:Word;
- Adaptador:Byte;
- Tabla : Tbuffer;
- Ptabpardis : Ptable;
- { --- Parámetros Lógicos --- }
- Unidad_Logica : Byte;
- Tipo_Unidad : Tipounidad;
- Sectores_Reservados,
- Entradas_Dir_Raiz,
- Sectores_Por_Fat,
- Primer_Sector_Logico : Word;
- Numero_De_Fats,
- Descriptor_De_Medio : Byte;
- Sectores_Totales,Clusters_Totales,
- Clusters_Libres,Bytes_Por_Sector : Word;
- Espacio_Libre,Capacidad_Total,Dirtabla : Longint;
- Sectores_Por_Cluster,
- Bytes_Por_Cluster : Word;
- Num_Unidades : Byte;
- Es_Hd : Boolean;
- Numero_Error : Word;
- Sector,Arranque : Tsector;
- Pista : Tpista;
- { ** Inicialización ** }
- Constructor Init(Unidad:Byte);
- Function Actualizar:Word;
- { ** Leer ** }
- Function Leesector(Cara,Pist,Sect:Integer):Byte;
- Function Leepista(Cara,Pist:Integer):Byte;
- { ** Grabar ** }
- Function Grabapista(Cara,Pist:Integer):Byte;
- { ** Verificar ** }
- Function Verificapista(Cara,Pist:Integer):Byte;
- { ** Formato ** }
- Function Format(Cara,Pist:Byte):Byte;
- Function Definemedio(Ps:Word;Sp:Byte):Byte;
- Function Definetipo(Tp:Byte):Byte;
- { ** Hardware ** }
- Procedure Reinicia_Unidad;
- Function Buscar_Tipo_Unidad:Tipounidad;
- { ** Cargar y salvar areas ** }
- Function Leer_Arranque:Word;
- { ** Finalización ** }
- Destructor Done;Virtual;
- { ** int 25h int 26h ** }
- Function Abswritesec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;
- Function Absreadsec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;
- Private
- { ** int 13h sectores y pistas ** }
- Function Usasector(Servicio,Cara,Pist,Sect:Integer):Byte;
- Function Usapista(Servicio,Cara,Pist:Integer):Byte;
- { ** Cálculos ** }
- Function Calcula_Capacidad:Byte;
- End;
-
- Implementation
-
- Constructor Tdrive.Init;
- Begin
- Tobject.Init;
- Unidad_Logica:=Unidad;
- Reinicia_Unidad;
- Numero_Error:=Actualizar;
- End;
-
- Function Tdrive.Usasector(Servicio,Cara,Pist,Sect:Integer):Byte;
- Var R:Registers;
- Begin
- R.Ah:=Servicio;
- R.Al:=1;
- R.Ch:=Pist;
- R.Cl:=Sect;
- R.Dh:=Cara;
- R.Dl:=Numero_Fisico;
- R.Es:=Seg(Sector);
- R.Bx:=Ofs(Sector);
- Intr($13,R);
- If R.Flags And Fcarry=Fcarry Then
- Usasector:=R.Ah
- Else
- Usasector:=0;
- End;
-
- Function Tdrive.Leesector(Cara,Pist,Sect:Integer):Byte;
- Begin
- Leesector:=Usasector(Cread,Cara,Pist,Sect);
- End;
-
- Function Tdrive.Grabapista(Cara,Pist:Integer):Byte;
- Begin
- Grabapista:=Usapista(Cwrite,Cara,Pist);
- End;
-
- Function Tdrive.Leer_Arranque:Word;
- Begin
- {Leer_Arranque:=Leesector(0,0,1); <- Es lo mismo }
- Leer_Arranque:=Absreadsec(Unidad_Logica,1,0,Ofs(Sector),Seg(Sector));
- Arranque:=Sector;
- End;
-
- Function Tdrive.Leepista(Cara,Pist:Integer):Byte;
- Begin
- Leepista:=Usapista(Cread,Cara,Pist);
- End;
-
- Function Tdrive.Verificapista(Cara,Pist:Integer):Byte;
- Begin
- Verificapista:=Usapista(Cverify,Cara,Pist);
- End;
-
- Function Tdrive.Usapista(Servicio,Cara,Pist:Integer):Byte;
- Var R:Registers;
- Begin
- With R Do Begin
- Ax:=Servicio*256+Sectores_Por_Pista;
- Dx:=Cara*256+Numero_Fisico;
- Cx:=Pist*256+1;
- Es:=Seg(Pista);
- Bx:=Ofs(Pista);
- End;
- Intr($13,R);
- If R.Flags And Fcarry=Fcarry Then
- Usapista:=R.Ah
- Else Usapista:=0;
- End;
-
- Destructor Tdrive.Done;
- Begin
- Reinicia_Unidad;
- Tobject.Done;
- End;
-
- Function Tdrive.Actualizar:Word;
- Var B:Byte;
- C:Word;
-
- Begin
- Actualizar:=0;
- Repeat
- Numero_Error:=Leer_Arranque;
- Until Not(Numero_Error In [6,3]);
- If Numero_Error>0 Then Begin
- Actualizar:=Numero_Error;
- Numero_Fisico:=Unidad_Logica;
- Exit;
- End;
- Numero_Fisico:=Unidad_Logica;
- Numero_Error:=Calcula_Capacidad;
- If Numero_Error>0 Then Begin
- Actualizar:=Numero_Error;
- Numero_Fisico:=Unidad_Logica;
- Exit;
- End;
- Es_Hd:=Numero_Fisico>=$80;
- Sectores_Por_Pista:=Arranque[25]+Arranque[26]*256;
- If Not(Sectores_Por_Pista In [8,9,15,18,36]) Then Begin
- Actualizar:=Cerrsecporpinc;
- Exit;
- End;
- If Es_Hd Then Numero_Error:=1; { Solo disquetes }
- If Numero_Error>0 Then Begin
- If Numero_Error=1 Then Numero_Error:=Cerrunidileg;
- Actualizar:=Numero_Error;
- Exit;
- End;
- Bytes_Por_Sector:=Arranque[12]+Arranque[13]*256;
- If Bytes_Por_Sector<>512 Then Begin
- Actualizar:=Cerrbytessecinc;
- Exit;
- End;
- Sectores_Por_Cluster:=Arranque[14];
- If Not(Sectores_Por_Cluster In [1,2]) Then Begin
- Actualizar:=Cerrsecporclinc;
- Exit;
- End;
- Sectores_Totales:=Arranque[20]+Arranque[21]*256;
- Descriptor_De_Medio:=Arranque[22];
- If Not(Descriptor_De_Medio In [$F0,$Fc..$Ff,$F9]) Then Begin
- Actualizar:=Cerrdescrmedinc;
- Exit;
- End;
- Cabezas:=Arranque[27]+Arranque[28]*256;
- If Sectores_Totales*Sectores_Por_Pista*Cabezas=0 Then Begin
- Actualizar:=$86;
- Exit;
- End;
- Pistas:=Word(Sectores_Totales Div (Sectores_Por_Pista*Cabezas));
- Entradas_Dir_Raiz:=Arranque[$12];
- Sectores_Reservados:=Arranque[$0F]+Arranque[$10]*256;
- Numero_De_Fats:=Arranque[$11];
- Sectores_Por_Fat:=Arranque[$17];
- Primer_Sector_Logico:=Sectores_Reservados+
- (Numero_De_Fats*Sectores_Por_Fat)+
- (Entradas_Dir_Raiz*32) Div 512;
- Tipo_Unidad:=Buscar_Tipo_Unidad;
- End;
-
- Function Tdrive.Absreadsec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;Assembler;
- Asm
- Push Ds
- Mov Al,u
- Mov Cx,Nsec
- Mov Dx,Psec
- Mov Ds,Segmento
- Mov Bx,Desplazamiento
- Int 25h
- Pushf
- Pop Bx
- Mov Cx,Fcarry
- And Bx,Cx
- Cmp Bx,Fcarry
- Jz @@1
- Xor Ax,Ax
- @@1:
- Popf
- Pop Ds
- End;
-
- Function Tdrive.Abswritesec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;Assembler;
- Asm
- Push Ds
- Mov Al,u
- Mov Cx,Nsec
- Mov Dx,Psec
- Mov Ds,Segmento
- Mov Bx,Desplazamiento
- Int 26h
- Pushf
- Pop Bx
- Mov Cx,Fcarry
- And Bx,Cx
- Cmp Bx,Fcarry
- Jz @@1
- Xor Ax,Ax
- @@1:
- Popf
- Pop Ds
- End;
-
- Function Tdrive.Calcula_Capacidad:Byte;
- Var R:Registers;
- Begin
- R.Ax:=$3600;
- R.Dl:=$00+Unidad_Logica+1;
- Msdos(R);
- Sectores_Por_Cluster:=R.Ax;
- Clusters_Libres:=R.Bx;
- Bytes_Por_Sector:=R.Cx;
- Clusters_Totales:=R.Dx;
- Espacio_Libre:=Sectores_Por_Cluster*Clusters_Libres;
- Espacio_Libre:=Espacio_Libre*Bytes_Por_Sector;
- Capacidad_Total:=Sectores_Por_Cluster*Clusters_Totales;
- Capacidad_Total:=Capacidad_Total*Bytes_Por_Sector;
- If R.Ax=$Ffff Then
- Calcula_Capacidad:=$86
- Else
- Calcula_Capacidad:=0;
- End;
-
- Function Tdrive.Format(Cara,Pist:Byte):Byte;
- Var Sec:Byte;
- R:Registers;
- Begin
- With R Do Begin
- Ah:=Cformat;
- Al:=Sectores_Por_Pista;
- Dx:=Cara*256+Numero_Fisico;
- Cx:=Pist*256;
- Es:=Seg(Tabla);
- Bx:=Ofs(Tabla);
- End;
- For Sec:=1 To Sectores_Por_Pista Do Begin
- Tabla[Sec*4-3]:=Pist;
- Tabla[Sec*4-2]:=Cara;
- Tabla[Sec*4-1]:=Sec;
- Tabla[Sec*4]:=2; (* 512 Bytes/Sector *)
- End;
- Intr($13,R);
- If R.Flags And Fcarry=Fcarry Then
- Format:=R.Ah
- Else Format:=0;
- End;
-
- Procedure Tdrive.Reinicia_Unidad;
- Var R:Registers;
- Begin
- R.Ah:=0;
- R.Dl:=Numero_Fisico;
- Intr($13,R);
- End;
-
- Function Tdrive.Definemedio(Ps:Word;Sp:Byte):Byte;
- Var R:Registers;
- Begin
- R.Ah:=$18;
- R.Ch:=Ps;
- R.Cl:=Sp;
- R.Dl:=Numero_Fisico;
- Intr($13,R);
- If R.Flags And Fcarry=Fcarry Then
- Definemedio:=R.Ah
- Else Begin
- Definemedio:=0;
- Ptabpardis:=Ptr(R.Es,R.Di);
- Dirtabla:=Longint(Ptabpardis);
- Setintvec($1E,Ptabpardis);
- End;
-
- End;
- (* FuncióN Obsoleta *)
- Function Tdrive.Definetipo(Tp:Byte):Byte;
- Var R:Registers;
- Begin
- R.Ah:=$17;
- R.Al:=Tp;
- R.Dl:=Numero_Fisico;
- Intr($13,R);
- If (R.Flags And 1)=1 Then
- Definetipo:=R.Ah
- Else
- Definetipo:=0;
- End;
-
- Function Tdrive.Buscar_Tipo_Unidad:Tipounidad;
- Var R:Registers;
- Begin
- R.Ah:=$08;
- R.Dl:=Numero_Fisico;
- Intr($13,R);
- Buscar_Tipo_Unidad:=Tipounidad(R.Bl);
- End;
-
-
- End.
-